#pragma once
#include "Socket.hpp"
#include "Protocol.hpp"
#include "pthread.h"
#include "functional"
class TcpServer;
using func_t = std::function<void(NetWork::Socket*)>;
class PthreadData{
    public:
    PthreadData(TcpServer* tcp, NetWork::Socket* socket)
        :_tcp(tcp),_socket(socket)
    {
    }
    TcpServer*  _tcp;
    NetWork::Socket* _socket;
};
class TcpServer
{
public:
    TcpServer(uint16_t port,func_t handle) : _port(port), _tcpserversocket(new NetWork::TcpSocket()),_handle(handle)
    {
    }
    static void* handerRounting(void* args)
    {
        pthread_detach(pthread_self());
        PthreadData* ptr = static_cast<PthreadData*>(args);
        ptr->_tcp->_handle(ptr->_socket);
        ptr->_socket->CloseSockFd();
        delete ptr->_socket;
        delete ptr;
        return nullptr;
    }
    void Loop()
    {
        _tcpserversocket->BuildListenSocket(_port, Backlog);
        while (true)
        {
            std::string peer;
            uint16_t peerport;
            NetWork::Socket* newsocket = _tcpserversocket->AcceptSocket(&peer, &peerport);
            std::cout << "newsockfd: " << newsocket->GetSockFd() << std::endl;
            pthread_t pid;
            PthreadData* pd = new PthreadData(this,newsocket);
            pthread_create(&pid,nullptr,handerRounting,pd);
        }
    }
    ~TcpServer()
    {
        delete _tcpserversocket;
    }

private:
    uint16_t _port;
    NetWork::Socket *_tcpserversocket;
public:
    func_t _handle;
};